/*
 * @Author: Oscar Pena
 * CS431 Fall 2011
 * this is just for testing the Simulator Window as a separate module
 * */

package FlowGram.Application.SimulatorWindow.SimulatorInterface;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;

import FlowGram.Application.Parser.Controllers.FinchController;
import FlowGram.Application.Parser.FinchExecutionLogger;
import FlowGram.Application.Parser.FinchParser;
import FlowGram.Application.Parser.FinchProgramFlow;
import FlowGram.Application.Parser.SystemOutExecutionLogger;
import FlowGram.Application.Parser.Utility.Configuration;
import FlowGram.Application.Parser.Prototype.FinchParserPrototype;
import FlowGram.Application.SimulatorWindow.SimulationWindow;
import FlowGram.Application.SimulatorWindow.Simulator.SimulationController;
import FlowGram.Application.SimulatorWindow.Simulator.SimulatorEngine;

public class SimulatorInterface {
	
		
	public static void main(String[] args) throws Exception {
	
	
		SimulationWindow simWin = new SimulationWindow();
		Configuration.setDefault("config.xml");

		FinchParser parser = new FinchParser();
		FinchExecutionLogger logger = new SystemOutExecutionLogger();
		((SystemOutExecutionLogger)logger).setPrefix("  ");
		String input = "repeat.finch"; //scanner.nextLine();
		String programBuffer = "";
		try {
		    BufferedReader in = new BufferedReader(findFile(input));
		    String str;
		    while ((str = in.readLine()) != null) {
		        programBuffer += str + "\n";
		    }
		    in.close();
		}catch(FileNotFoundException e){
			//System.out.println(e.getMessage());
		}catch (IOException e) {
			System.out.println("Error reading file.");
		}
		//System.out.println(programBuffer);
		FinchProgramFlow flow = parser.Parse(programBuffer);
		//System.out.println(flow);
		if (flow == null){
			
			//System.out.println("yes");
		}
		simWin.set_simulation(flow);
		simWin.setVisible(true);
		//System.out.println("interface");
	}

		
	
	
protected static FileReader findFile(String path) throws FileNotFoundException{
	ArrayList<String> includepath = getIncludePaths();
	includepath.add(0, "");
	
	int currPath = 0;
	FileReader fr;
	while(currPath < includepath.size()){
		try{
			fr = getFile(includepath.get(currPath)+path);
			return fr;
		}catch(FileNotFoundException e){
			currPath++;
			continue;
		}
	}
	throw new FileNotFoundException("Could not find file '"+path+"'");
}



protected static FileReader getFile(String path) throws FileNotFoundException{
	//System.out.println("attempting to open '"+path+"'");
	FileReader r = null;
	try {
		r = new FileReader(URLDecoder.decode(path, "UTF-8"));
	} catch (UnsupportedEncodingException e) {
		// TODO Auto-generated catch block
		//e.printStackTrace();
	}
	return r;
}


protected static ArrayList<String> getIncludePaths(){
	ArrayList<String> includepaths = new ArrayList<String>();
	Configuration config;
	try{
		config = Configuration.getInstance();
	}catch(Exception e){
		return includepaths;
	}
	String appPath = getApplicationPath();//.replaceAll("\\", "\\\\");
	if(appPath.endsWith("/")){
		appPath = appPath.substring(0, appPath.length()-1);
	}
	if(appPath.startsWith("/")){
		appPath = appPath.substring(1);
	}
	String[] paths = config.config.getStringArray("includepaths.path");
	for(int i=0; i < paths.length; i++){
		
		String path = paths[i].replaceAll("\\$\\{finchpath\\}", Matcher.quoteReplacement(appPath));
		includepaths.add(path);
	}
	return includepaths;
}
protected static String getApplicationPath(){
	String applicationDir = FinchParserPrototype.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 
	return applicationDir;
	/*
	if (applicationDir.endsWith(".exe")){
	    applicationDir = new File(applicationDir).getParent();
	}else{
	    // Add the path to the class files  
	    applicationDir += FinchParserPrototype.class.getName().replace('.', '/');

	    // Step one level up as we are only interested in the 
	    // directory containing the class files
	    applicationDir = new File(applicationDir).getParent();
	}
	return applicationDir;
	*/
}


protected static ArrayList<FinchController> loadControllers() throws Exception{
	ArrayList<FinchController> controllers = new ArrayList<FinchController>();
	
	Configuration config = Configuration.getInstance();
	String[] ctrls = config.config.getStringArray("finchcontrollers.controller");
	for(int i=0; i < ctrls.length; i++){
		Class controlClass = Class.forName(ctrls[i]);
		Constructor construct = controlClass.getConstructor(null);
		FinchController cInstance = (FinchController)construct.newInstance(null);
		controllers.add(cInstance);
	}
	return controllers;
}

}